package cn.com.ghy.android.util;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.StringWriter;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlSerializer;

import android.util.Xml;

/**
 * @软件著作权:金红叶纸业集团有限公司
 * @系统名称:SFA系统
 * @Description:xml解析器,负责创建XML格式和解析XML格式
 * @author wuz @date 2012-01-12 16:10:16
 * @版本历史:v1.0
 * @Copyright:Copyright (c) 2011-2012
 */

public class XMLParseUtils {

	public static <T> String createXMLOfBean(List<T> content) {
		if (content == null || content.size() == 0) {
			throw new RuntimeException("需要XML格式化的内容为空!");
		}

		StringWriter writer = null;
		try {
			writer = new StringWriter();
			XmlSerializer xmlSerializer = Xml.newSerializer();
			xmlSerializer.setOutput(writer);
			xmlSerializer.startDocument("UTF-8", true);
			xmlSerializer.startTag("", XMLStatic.CONTENT);
			xmlSerializer.attribute("", XMLStatic.TOTAL_RECORD, String.valueOf(content.size()));

			for (T t : content) {
				xmlSerializer.startTag("", XMLStatic.RECORDS);
				Field[] fields = t.getClass().getDeclaredFields();
				for (Field field : fields) {
					field.setAccessible(true);
					String tag = field.getName().toUpperCase();
					if (tag.equalsIgnoreCase("SERIALVERSIONUID")) {
						continue;
					}
					xmlSerializer.startTag("", tag);
					try {
						Object obj = field.get(t);
						xmlSerializer.text(obj == null ? "" : obj.toString());
					} catch (Exception e) {
						throw new RuntimeException("转换类型错误！");
					}
					xmlSerializer.endTag("", tag);
				}
				xmlSerializer.endTag("", XMLStatic.RECORDS);
			}

			xmlSerializer.endTag("", XMLStatic.CONTENT);
			xmlSerializer.endDocument();
		} catch (Exception e) {
			throw new RuntimeException("创建XML格式String时错误!", e);
		} finally {
			if (writer != null) {
				writer.flush();
				try {
					writer.close();
				} catch (IOException e) {
					throw new RuntimeException("关闭写入流错误!", e);
				}
			}
		}

		return writer.toString().replace(
				"<?xml version='1.0' encoding='UTF-8' standalone='yes' ?>", "");

	}

	public static String createXML(List<Map<String, String>> content) {

		if (content == null || content.size() == 0) {
			throw new RuntimeException("需要XML格式化的内容为空!");
		}

		StringWriter writer = null;
		try {
			writer = new StringWriter();
			XmlSerializer xmlSerializer = Xml.newSerializer();
			xmlSerializer.setOutput(writer);
			xmlSerializer.startDocument("UTF-8", true);
			xmlSerializer.startTag("", XMLStatic.CONTENT);
			xmlSerializer.attribute("", XMLStatic.TOTAL_RECORD, String.valueOf(content.size()));
			xmlSerializer.startTag("", XMLStatic.RECORDS);

			for (Map<String, String> map : content) {
				Iterator<Entry<String, String>> it = map.entrySet().iterator();
				while (it.hasNext()) {
					Entry<String, String> entry = it.next();
					xmlSerializer.startTag("", entry.getKey().toUpperCase());
					xmlSerializer.text(entry.getValue().trim());
					xmlSerializer.endTag("", entry.getKey().toUpperCase());
				}
			}

			xmlSerializer.endTag("", XMLStatic.RECORDS);
			xmlSerializer.endTag("", XMLStatic.CONTENT);
			xmlSerializer.endDocument();
		} catch (Exception e) {
			throw new RuntimeException("创建XML格式String时错误!", e);
		} finally {
			if (writer != null) {
				writer.flush();
				try {
					writer.close();
				} catch (IOException e) {
					throw new RuntimeException("关闭写入流错误!", e);
				}
			}
		}

		return writer.toString().replace(
				"<?xml version='1.0' encoding='UTF-8' standalone='yes' ?>", "");
	}

	@SuppressWarnings("unchecked")
	public static <T> List<T> parseXML(String startTag, byte[] bytes, Class<T> clazz) {
		if (startTag == null || "".equals(startTag)) {
			startTag = "Table";
		}

		List<T> list = new ArrayList<T>();

		if (bytes.length == 0) {
			return list;
		}

		T inits = null;
		InputStream in = null;

		String className = clazz.getName();
		T obj = null;
		try {
			obj = (T) Class.forName(clazz.getName());
		} catch (ClassNotFoundException e) {
			throw new RuntimeException("无法解析类型!", e);
		}

		Method[] methods = ((Class<T>) obj).getMethods();
		Map<String, Method> map = new HashMap<String, Method>();
		for (int i = 0; i < methods.length; i++) {
			if ("set".equals(methods[i].getName().substring(0, 3))) {
				map.put(methods[i].getName().substring(3).toUpperCase(), methods[i]);
			}
		}

		try {
			in = new ByteArrayInputStream(bytes);
			XmlPullParser parser = Xml.newPullParser();
			parser.setInput(in, "UTF-8");
			int type = parser.getEventType();

			while (type != XmlPullParser.END_DOCUMENT) {
				switch (type) {
					case XmlPullParser.START_DOCUMENT :
						break;

					case XmlPullParser.START_TAG :
						if (startTag.equals(parser.getName())) {
							inits = (T) Class.forName(className).newInstance();
						} else if (map.size() != 0) {
							Iterator<Entry<String, Method>> it = map.entrySet().iterator();
							while (it.hasNext()) {
								Entry<String, Method> entry = it.next();
								if (entry.getKey().equals(parser.getName())) {
									entry.getValue().invoke(inits, parser.nextText().trim());
								}
							}
						}
						break;

					case XmlPullParser.END_TAG :
						if (startTag.equals(parser.getName())) {
							list.add(inits);
						}
						break;
				}
				type = parser.next();
			}
		} catch (Exception e) {
			throw new RuntimeException("解析XML错误!", e);
		} finally {
			if (in != null) {
				try {
					in.close();
				} catch (IOException e) {
					throw new RuntimeException("关闭解析流错误!", e);
				}
			}
		}
		return list;
	}

	public static <T> List<T> parseXML(byte[] bytes, Class<T> clazz) {
		return parseXML(null, bytes, clazz);
	}
}
